package com.yeskery.nut.http;

import com.yeskery.nut.core.*;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 该类是基于URL Encoded 方式请求下的 {@link Request} 实现，
 * 该类的实现方式基于一个 {@link BaseRequest}对象。
 * @author sprout
 * 2019-03-15 11:36
 * @version 1.0
 */
public class UrlEncodedRequest extends AbstractWrapperRequest implements Serializable, Cloneable {

	/**
	 * 构建一个 {@link UrlEncodedRequest} 对象
	 * @param baseRequest 基础数据对象 {@link BaseRequest} 对象
	 */
	public UrlEncodedRequest(BaseRequest baseRequest) {
		super(baseRequest);
		String parameterValues = new String(baseRequest.body, StandardCharsets.UTF_8);
		String[] paras = parameterValues.split("&");
		for (String paraValue : paras) {
			String[] paraValues = paraValue.split("=");
			if (paraValues.length < 2) {
				continue;
			}
			String value;
			try {
				value = URLDecoder.decode(paraValues[1], StandardCharsets.UTF_8.name());
			} catch (UnsupportedEncodingException e) {
				value = paraValues[1];
			}
			baseRequest.queryParameters.computeIfAbsent(paraValues[0].trim(), k -> new ArrayList<>()).add(value);
			baseRequest.parameters.computeIfAbsent(paraValues[0].trim(), k -> new ArrayList<>()).add(value);
 		}
	}

	@Override
	public List<String> getHeaders(String key) {
		return getBaseRequest().getHeaders(key);
	}

	@Override
	public String getHeader(String key) {
		return getBaseRequest().getHeader(key);
	}

	@Override
	public Map<String, List<String>> getHeaders() {
		return getBaseRequest().getHeaders();
	}

	@Override
	public Set<String> getParameterKeys() {
		return getBaseRequest().getParameterKeys();
	}

	@Override
	public Method getMethod() {
		return getBaseRequest().getMethod();
	}

	@Override
	public String getOriginalPath() {
		return getBaseRequest().getOriginalPath();
	}

	@Override
	public String getPath() {
		return getBaseRequest().getPath();
	}

	@Override
	public String getProtocol() {
		return getBaseRequest().getProtocol();
	}

	@Override
	public String getRemoteAddress() {
		return getBaseRequest().getRemoteAddress();
	}

	@Override
	public String getRemoteHost() {
		return getBaseRequest().getRemoteHost();
	}

	@Override
	public int getRemotePort() {
		return getBaseRequest().getRemotePort();
	}

	@Override
	public String getLocalAddress() {
		return getBaseRequest().getLocalAddress();
	}

	@Override
	public String getLocalHost() {
		return getBaseRequest().getLocalHost();
	}

	@Override
	public int getLocalPort() {
		return getBaseRequest().getLocalPort();
	}

	@Override
	public ServerRequestConfiguration getServerRequestConfiguration() {
		return getBaseRequest().getServerRequestConfiguration();
	}

	@Override
	public Cookie[] getCookies() {
		return getBaseRequest().getCookies();
	}

	@Override
	public boolean hasCookie(String name) {
		return getBaseRequest().hasCookie(name);
	}

	@Override
	public List<MultipartFile> getFiles(String key) {
		return getBaseRequest().getFiles(key);
	}

	@Override
	public byte[] getBody() {
		return getBaseRequest().getBody();
	}

	@Override
	public Map<String, List<String>> getParametersMap() {
		return getBaseRequest().getParametersMap();
	}

	@Override
	public Map<String, List<String>> getQueryParametersMap() {
		return getBaseRequest().getQueryParametersMap();
	}

	@Override
	public void addAttribute(String name, Object value) {
		getBaseRequest().addAttribute(name, value);
	}

	@Override
	public void removeAttribute(String name) {
		getBaseRequest().removeAttribute(name);
	}

	@Override
	public Object getAttribute(String name) {
		return getBaseRequest().getAttribute(name);
	}

	@Override
	public Map<String, Object> getAttributes() {
		return getBaseRequest().getAttributes();
	}

	@Override
	public Session getSession() {
		return getBaseRequest().getSession();
	}

	@Override
	public ServerContext getServerContext() {
		return getBaseRequest().getServerContext();
	}

	@Override
	public boolean isEmpty() {
		return getBaseRequest().isEmpty();
	}

	@Override
	public UrlEncodedRequest clone() {
		try {
			return (UrlEncodedRequest) super.clone();
		} catch (CloneNotSupportedException e) {
			throw new NutException(e);
		}
	}
}
